﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Input;
using ABCat.Core;
using ABCat.Core.Plugins.DataSets;
using ABCat.Core.Plugins.Sites;
using ABCat.Shared;
using ABCat.Shared.Properties;
using ABCat.UI.WPF.UI;

namespace ABCat.UI.WPF.Models
{
	public class RecordTargetDownloaderViewModel : AsyncOperationViewModelBase
	{
		#region + Fields +

		private LoginInfo _loginInfo;
		private readonly Context _context;
		private readonly IRecordTargetDownloaderPlugin _recordTargetDownloaderPlugin;
		private readonly Func<IEnumerable<IAudioBook>> _getSelectedRecordsFunc;
		private readonly Action _recordDownloadedCallback;
		private readonly DelegateCommand _downloadRecordTargetCommand;

		#endregion
		#region + Properties +

		[UsedImplicitly]
		public DelegateCommand DownloadRecordTargetCommand
		{
			get
			{
				return _downloadRecordTargetCommand;
			}
		}

		#endregion
		#region + Ctor +

		public RecordTargetDownloaderViewModel([NotNull] Context context, [NotNull] StatusBarStateViewModel statusBarStateModel,
		                                   [NotNull] IRecordTargetDownloaderPlugin recordTargetDownloaderPlugin,
		                                   [NotNull] Func<IEnumerable<IAudioBook>> getSelectedRecordsFunc,
		                                   [NotNull] Action recordDownloadedCallback)
			: base(statusBarStateModel)
		{
			_context = context;
			_recordTargetDownloaderPlugin = recordTargetDownloaderPlugin;
			_getSelectedRecordsFunc = getSelectedRecordsFunc;
			_recordDownloadedCallback = recordDownloadedCallback;
			_downloadRecordTargetCommand = new DelegateCommand(OnDownloadRecordTarget, (obj) => CancellationTokenSource == null);
		}

		#endregion
		#region + Logic +

		public void OnDownloadRecordTarget(object parameter)
		{
			//LoginInfo loginInfo = _loginInfo;

			//if (loginInfo == null || !loginInfo.Check())
			//{
			//	loginInfo = GetLoginInfo(loginInfo);
			//}

			//if (loginInfo.Check())
			{
				CancellationTokenSource = new CancellationTokenSource();
				var targetRecords = new HashSet<string>(_getSelectedRecordsFunc().Select(item => item.Key));

				_recordTargetDownloaderPlugin.BeginDownloadRecordTargetAsync(targetRecords,
					ReportProgressSmall,
					ReportProgressTotal,
					DownloadRecordTargetAsyncCompleted,
					CancellationTokenSource.Token);
			}
		}

		private void DownloadRecordTargetAsyncCompleted(Exception ex)
		{
			_context.UiDispatcher.CheckAccess(() =>
				{
					OnAsynOperationCompleted();
					CommandManager.InvalidateRequerySuggested();

					if (ex == null) _recordDownloadedCallback();
					else throw ex;
				});
		}

		public static LoginInfo ShowLoginWindow(LoginInfo loginInfo)
		{
			var loginWindow = new LoginWindow();
			loginWindow.LoginInfo = loginInfo ?? new LoginInfo();
			if (loginWindow.ShowDialog() != true) return null;
			LoginInfo result = loginWindow.LoginInfo;
			return result;
		}

		#endregion
	}
}